package syntax;

import java.util.HashSet;

import common.TokenType;

public class FirstSet {
	HashSet<TokenType> set = new HashSet<TokenType>();
	
	public FirstSet( NonterminalType type ){
		switch(type){
		case declaration : 
			set.add(TokenType.INT);
			set.add(TokenType.BOOL);
			set.add(TokenType.VOID);
			break;
		case nonVoidSpecifier:
			set.add( TokenType.INT );
			set.add( TokenType.BOOL );
			break;
		case decTail:
			set.add( TokenType.LSQR );
			set.add( TokenType.SEMI );
			set.add( TokenType.COMMA );
			set.add( TokenType.LPAREN );			
			break;
		case varDecTail:
			set.add( TokenType.LSQR );
			set.add( TokenType.SEMI );
			set.add( TokenType.COMMA );
			break;
		case varName:
			set.add( TokenType.ID );
			break;
		case funDecTail:
			set.add( TokenType.LPAREN );
			break;
		case params:
			set.add( TokenType.REF );
			set.add( TokenType.INT );
			set.add( TokenType.BOOL );
			set.add( TokenType.VOID );
			break;
		case param:
			set.add( TokenType.REF );
			set.add( TokenType.INT );
			set.add( TokenType.BOOL );
			break;
		case statement:
			set.add( TokenType.LCRLY );
			set.add( TokenType.IF );
			set.add( TokenType.LOOP );
			set.add( TokenType.EXIT );
			set.add( TokenType.EXIT );
			set.add( TokenType.CONTINUE );
			set.add( TokenType.RETURN );
			set.add( TokenType.SEMI );
			set.add( TokenType.ID );
			set.add( TokenType.BRANCH );
			break;
		case idStmt:
			set.add( TokenType.ID );
			break;
		case idStmtTail:
			set.add( TokenType.LSQR );
			set.add( TokenType.ASSIGN );
			set.add( TokenType.LPAREN );
			break;
		case assignStmtTail:
			set.add( TokenType.LSQR );
			set.add( TokenType.ASSIGN );
			break;
		case callStmtTail:
			set.add( TokenType.LPAREN );
			break;
		case callTail:
			set.add( TokenType.LPAREN );
			break;
		case arguments:
			set.add( TokenType.MINUS );
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			set.add( TokenType.ID );
			break;
		case compoundStmt :
			set.add( TokenType.LCRLY );
			break;
		case ifStmt :
			set.add( TokenType.IF );
			break;
		case loopStmt:
			set.add( TokenType.LOOP );
			break;
		case exitStmt :
			set.add( TokenType.EXIT );
			break;
		case continueStmt :
			set.add( TokenType.CONTINUE );
			break;
		case returnStmt :
			set.add( TokenType.RETURN );
			break;
		case nullStmt :
			set.add( TokenType.SEMI );
			break;
		case branchStmt :
			set.add( TokenType.BRANCH );
			break;
		case caseStmt:
			set.add( TokenType.CASE );
			set.add( TokenType.DEFAULT );
			break;
		case expression:
			set.add( TokenType.MINUS );
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			set.add( TokenType.ID );
			break;
		case addExp :
			set.add( TokenType.MINUS );
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			set.add( TokenType.ID );
			break;
		case term:
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			set.add( TokenType.ID );
			break;
		case factor :
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			set.add( TokenType.ID );
			break;
		case nidFactor :
			set.add( TokenType.NOT );
			set.add( TokenType.LPAREN );
			set.add( TokenType.NUM );
			set.add( TokenType.BLIT );
			break;
		case idFactor :
			set.add( TokenType.ID );
			break;
		case idTail :
			set.add( TokenType.LSQR );
			set.add( TokenType.LPAREN );
			break;
		case varTail:
			set.add( TokenType.LSQR );
			break;
		case relop:
			set.add( TokenType.LTEQ );
			set.add( TokenType.LT );
			set.add( TokenType.GT );
			set.add( TokenType.GTEQ );
			set.add( TokenType.EQ );
			set.add( TokenType.NEQ );
			break;
		case addop:
			set.add( TokenType.PLUS );
			set.add( TokenType.MINUS );
			set.add( TokenType.OR );
			set.add( TokenType.ORELSE );
			break;
		case multop:
			set.add( TokenType.MULT );
			set.add( TokenType.DIV );
			set.add( TokenType.MOD );
			set.add( TokenType.AND );
			set.add( TokenType.ANDTHEN );
			break;
		case uminus:
			set.add( TokenType.MINUS );
			break;
		}
	}
	
	public Boolean contain( TokenType token ){
		return set.contains(token);
	}
	
	public int size()
	{
		return set.size();
	}
}
